package com.xh3140.android.widget.dialog.view;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.LinearLayoutCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.xh3140.android.widget.dialog.params.ListParams;

import java.util.ArrayList;
import java.util.List;

public class ListView extends RecyclerView {
    private int mCheckedIndex = -1;
    private final List<Integer> mCheckedIndexList = new ArrayList<>();

    public ListView(@NonNull Context context) {
        this(context, new ListParams(context, 0));
    }

    public ListView(@NonNull Context context, @NonNull ListParams params) {
        super(context);
        configView(params);
    }

    /**
     * 获取单选的选取位置索引
     * 注意：没有选中任何项目时返回负数(-1)
     */
    public int getCheckedIndex() {
        return mCheckedIndex;
    }

    /**
     * 获取多选的选取位置索引列表
     * 注意：没有选中任何项目时返回空列表
     */
    public List<Integer> getCheckedIndexList() {
        return mCheckedIndexList;
    }

    /**
     * 配置视图
     *
     * @param params 列表主体视图配置属性
     */
    public void configView(@NonNull ListParams params) {
        setHasFixedSize(true);
        setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
        setLayoutParams(new LinearLayoutCompat.LayoutParams(
                LinearLayoutCompat.LayoutParams.MATCH_PARENT,
                LinearLayoutCompat.LayoutParams.WRAP_CONTENT, 1f));
        if (params.hasDivider) {
            addItemDecoration(ItemDivider.of(params.dividerColor, params.dividerThickness));
        }
        setAdapter(new ItemListAdapter(params));
        if (params.callback != null) {
            params.callback.callback(this);
        }
    }

    public static final class ItemViewHolder extends ViewHolder {
        public ItemViewHolder(@NonNull ItemView itemView) {
            super(itemView);
        }
    }

    /**
     * 适配器
     */
    class ItemListAdapter extends Adapter<ItemViewHolder> {
        private final ListParams mListParams;

        public ItemListAdapter(@NonNull ListParams params) {
            mListParams = params;
        }

        private void configCheckedChangedSingle(int position, boolean isChecked) {
            if (isChecked) {
                if (mCheckedIndex >= 0) {
                    // 手动取消前一个选中的项目
                    final int prevIndex = mCheckedIndex;
                    mListParams.items.get(prevIndex).isChecked = false;
                    if (isComputingLayout()) {
                        post(() -> notifyItemChanged(prevIndex));
                    } else {
                        notifyItemChanged(prevIndex);
                    }
                }
                // 选中当前项目
                mCheckedIndex = position;
                mListParams.items.get(position).isChecked = true;
            } else {
                // 取消当前项目
                if (mCheckedIndex == position) {
                    mCheckedIndex = -1;
                }
                mListParams.items.get(position).isChecked = false;
            }
        }

        private void configCheckedChangedMultiple(int position, boolean isChecked) {
            mListParams.items.get(position).isChecked = isChecked;
            if (isChecked) {
                if (!mCheckedIndexList.contains(position)) {
                    mCheckedIndexList.add(position);
                }
            } else {
                if (mCheckedIndexList.contains(position)) {
                    // 注意，这里必须是remove(Integer.valueOf(position))，不能是remove(position)
                    // remove(position)表示移除指定索引位置的值，会抛出异常
                    // remove(Integer.valueOf(position))表示移除数值是position的值，这个方法命名为removeAt更合适
                    mCheckedIndexList.remove(Integer.valueOf(position));
                }
            }
        }

        @Override
        public int getItemCount() {
            return mListParams.items.size();
        }

        @NonNull
        @Override
        public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            final ItemView view = new ItemView(parent.getContext(), mListParams.isSingle, mListParams.isRight);
            final ItemViewHolder holder = new ItemViewHolder(view);
            if (mListParams.isSingle) {
                view.setOnCheckedChangeListener((itemView, isChecked) -> configCheckedChangedSingle(holder.getAdapterPosition(), isChecked));
            } else {
                view.setOnCheckedChangeListener((itemView, isChecked) -> configCheckedChangedMultiple(holder.getAdapterPosition(), isChecked));
            }
            return holder;
        }

        @Override
        public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
            ((ItemView) holder.itemView).configView(mListParams.items.get(position));
        }
    }

    /**
     * 分割线
     */
    public static class ItemDivider extends ItemDecoration {
        private final Drawable mDivider;
        private final Rect mBounds = new Rect();

        @NonNull
        public static ItemDivider of(@ColorInt int color, int thickness) {
            final GradientDrawable drawable = new GradientDrawable();
            drawable.setColor(ColorStateList.valueOf(color));
            drawable.setSize(thickness, thickness);
            return new ItemDivider(drawable);
        }

        @NonNull
        public static ItemDivider of(@ColorInt int color, int thickness, int alpha) {
            final GradientDrawable drawable = new GradientDrawable();
            drawable.setColor(ColorStateList.valueOf(color));
            drawable.setSize(thickness, thickness);
            drawable.setAlpha(alpha);
            return new ItemDivider(drawable);
        }

        public ItemDivider(@NonNull Drawable divider) {
            mDivider = divider;
        }

        @Override
        public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull State state) {
            if (parent.getLayoutManager() == null) {
                return;
            }
            canvas.save();
            final int left, right;
            if (parent.getClipToPadding()) {
                left = parent.getPaddingLeft();
                right = parent.getWidth() - parent.getPaddingRight();
                final int top = parent.getPaddingTop();
                final int bottom = parent.getHeight() - parent.getPaddingBottom();
                canvas.clipRect(left, top, right, bottom);
            } else {
                left = 0;
                right = parent.getWidth();
            }
            final int dividerCount = parent.getChildCount() - 1;
            for (int i = 0; i < dividerCount; i++) {
                final View child = parent.getChildAt(i);
                parent.getDecoratedBoundsWithMargins(child, mBounds);
                final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
                final int top = bottom - mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
            canvas.restore();
        }
    }
}
